/**
 * Module Name: PassTwo
 * 
 * Description: Implements chart on page 15 of CRT
 * 
 * Calling Sequence: PassTwo passTwo = new PassTwo();
 * 
 * Input Parameters:
 * 
 * Output Parameters:
 * 
 * Error Conditions Tested:
 * 
 * Error Messages Generated:
 * 
 * Original Author:
 * 
 * Procedure Creation Date:
 * 
 * Modification Log: Who/When/Why
 * 
 * Coding Standards Met: "Signed Code Leader(Jaron)"
 * 
 * Testing Standards Met: "Signed Test Leader(Jamie)"
 */
public class PassTwo {
	protected static SymbolTable symbolTable = new SymbolTable();
	protected static ObjectFile objectFile = new ObjectFile();
	protected static AssemblyListing assemblyListing = new AssemblyListing();

	private static int currentLC;
	private static int lineNumber;
	private static int totalLC = AssemblyListing.totalLC;

	public static void run() {
		Main.appendDebugText(Main.newline + "Starting PassTwo");
		String lineNumberString = "";

		int totalCodeLength = AssemblyListing.size();
		Main.appendDebugText("Total Code Length: " + totalCodeLength);
		// lineNumber is initiated to 1 to avoid line zero in the intermediate
		// file
		lineNumber = 0;
		// Begin to process Intermediate file
		while (lineNumber < totalCodeLength) {
			int lineNum = lineNumber;
			lineNumberString = String.valueOf(lineNum);
			currentLC = AssemblyListing.returnLocationCounter(lineNumber);
			String currentInst = AssemblyListing.returnOperation(lineNumber);
			Main.appendDebugText("Operation: " + currentInst);
			if (MOTtable.mnemonicIsDefined(currentInst)) { // If instruction is
				if (ErrorHandler.lineHasErrorIntermediateError(lineNumber)) {
					processLineAsNOP();
				} else {
					// in MOT, process
					// here
					Integer evalOp = OperandEvaluator
							.evaluateOperand(lineNumber);

					if (evalOp > totalLC) {
						String fullOperand = AssemblyListing
								.returnFullOperand(lineNumber);
						ErrorHandler
								.addToErrorList(
										lineNumberString,
										"6",
										"The Operand "
												+ fullOperand
												+ " Evaluates to "
												+ evalOp.toString()
												+ "\tThis is greater than the total LC, "
												+ String.valueOf(totalLC - 1));
						processLineAsNOP();
					} else if (ErrorHandler
							.lineHasErrorIntermediateError(lineNumber)) {
						processLineAsNOP();
					} else {
						String opCode = AssemblyListing
								.returnBinaryOperation(lineNumber);
						String addrFlags = AssemblyListing
								.returnAddressFlags(lineNumber);
						String IRbit = AssemblyListing.returnIRBit(lineNumber);
						String ARbit = AssemblyListing.returnARBit(lineNumber);
						String BRbit = AssemblyListing.returnBRBit(lineNumber);
						String Bugbit = AssemblyListing
								.returnDebugBit(lineNumber);
						String addrField;

						if (AssemblyListing.lineUsedLiteral(lineNumber)) {
							String literal = AssemblyListing
									.returnLiteral(lineNumber);
							String literalAddress = SymbolTable
									.returnLocationAddress(literal);
							Integer litAddVal = Integer.valueOf(literalAddress);
							addrField = Integer.toBinaryString(litAddVal);

						} else {
							addrField = Integer.toBinaryString(evalOp);
						}
						while (addrField.length() > 11) {
							addrField = addrField.substring(1);
						}
						while (addrField.length() < 11) {
							addrField = "0" + addrField;
						}
						String macCode = opCode + IRbit + ARbit + BRbit
								+ Bugbit + addrFlags + addrField;
						AssemblyListing.addObjectCode(lineNumber, macCode);
						String relocationS1Code = "R";
						AssemblyListing.editRelocationCode(lineNumber, "R");
						if (currentInst.toUpperCase().contains("ABS")
								|| currentInst.toUpperCase().contains("SLA")
								|| currentInst.toUpperCase().contains("SRA")
								|| currentInst.toUpperCase().contains("SLL")
								|| currentInst.toUpperCase().contains("SRL")
								|| currentInst.toUpperCase().contains("RROT")
								|| currentInst.toUpperCase().contains("LROT")
								|| addrFlags.equalsIgnoreCase("100")) {
							relocationS1Code = "A";
							AssemblyListing.editRelocationCode(lineNumber, "A");
						} else if (BRbit == "1") {
							relocationS1Code = "B";
							AssemblyListing.editRelocationCode(lineNumber, "B");
						} else if (OperandEvaluator.usedExternal) {
							relocationS1Code = "C";
							AssemblyListing.editRelocationCode(lineNumber, "C");
						}
						String referencedS1Symbol = evalOp.toString();
						String sign = "+";
						ObjectFile.addTextRecord(currentLC, macCode,
								relocationS1Code, sign, referencedS1Symbol);

						// String rSymbol =
						// SymbolTable.returnRelocationCode(label);

						// macCodeHex = macCodeHex +

						// Instruction may be an error so there will be an
						// output for
						// error within this block
					}
				}

			} else if (POTtable.isDefined(currentInst)) {
				// first handle pseudo ops that do not consume memory

				// if current instruction is start
				if (currentInst.equalsIgnoreCase("start")) {
					// edit start and load addresses in header file
					ObjectFile.loadAddress = OperandEvaluator
							.evaluateOperand(lineNumber);
					ObjectFile.startAddress = OperandEvaluator
							.evaluateOperand(lineNumber);
					String moduleName = AssemblyListing.returnLabel(lineNumber);
					ObjectFile.moduleName = moduleName;
				}

				// if current instruction is alt-start
				else if (currentInst.equalsIgnoreCase("Alt-start")) {
					// edit start address in header file
					ObjectFile.startAddress = OperandEvaluator
							.evaluateOperand(lineNumber);
				}

				// if current instruction is entry
				else if (currentInst.equalsIgnoreCase("entry")) {
					// create entry records

					String[] opArray = ParseLine.parseOperands(AssemblyListing
							.returnFullOperand(lineNumber));

					for (String i : opArray) {
						if (i != null) {
							if (SymbolTable.symbolIsDefined(i)) {
								ObjectFile.addEntry(i, currentLC,
										AssemblyListing.returnLabel(0));
							} else {
								ErrorHandler
										.addToErrorList(
												lineNumberString,
												"22",
												"The Symbol "
														+ i
														+ " is an Undefined Entry Label");
							}
						}
						System.out.println("Operand is " + i);
					}
				}

				// handle pseudo ops that consume memory...
				if (POTtable.consumesMemory(currentInst)) {
					// if current instruction is word-num, word-char, word-bin,
					// word hex, or adr-comp...
					if (ErrorHandler.lineHasErrorIntermediateError(lineNumber)) {
						processLineAsNOP();
					} else {
						if ((currentInst.toUpperCase().contains("WORD") || currentInst
								.toUpperCase().contains("ADR"))) {
							Integer evalOp = OperandEvaluator
									.evaluateOperand(lineNumber);

							if (ErrorHandler
									.lineHasErrorIntermediateError(lineNumber)) {
								processLineAsNOP();
							} else {
								// machine code is evalOp...
								String macCode = Integer.toBinaryString(evalOp);

								while (macCode.length() < 24) {
									macCode = "0" + macCode;
								}
								while (macCode.length() > 24) {
									macCode = macCode.substring(1);
								}
								AssemblyListing.addObjectCode(lineNumber,
										macCode);
								if ((currentInst.toUpperCase().contains("WORD"))) {
									AssemblyListing.editRelocationCode(
											lineNumber, "A");
									String operand = AssemblyListing
											.returnFullOperand(lineNumber);
									String sign = "+";
									if (operand.charAt(0) == '-') {
										operand = operand.substring(0);
										sign = "-";
									}
									ObjectFile.addTextRecord(currentLC,
											macCode, "A", sign, Integer
													.toString(evalOp));
								} else if (currentInst.toUpperCase().contains(
										"ADR")) {
									if (OperandEvaluator.hasError) {
										processLineAsNOP();
									} else {
										if (OperandEvaluator.usedExternal) {
											macCode = "0";
											while (macCode.length() < 24) {
												macCode = "0" + macCode;
											}
											String operand = AssemblyListing
													.returnFullOperand(lineNumber);
											String[] operandA = ParseLine
													.parseExpressionKeepOperators(operand);

											int numOfOps = 1;
											String op1 = operandA[0];
											String op2 = operandA[1];
											String op3 = operandA[2];
											String op4 = operandA[3];
											String op5 = operandA[4];
											String sign1 = "+";
											String sign2 = "+";
											String sign3 = "+";
											String sign4 = "+";
											String sign5 = "+";
											String code1 = "R";
											String code2 = "R";
											String code3 = "R";
											String code4 = "R";
											String code5 = "R";
											String sp1 = "0";
											String sp2 = "0";
											String sp3 = "0";
											String sp4 = "0";
											String sp5 = "0";

											if (op1.charAt(0) == '-') {
												sign1 = "-";
												op1 = op1.substring(1);
											}

											if (op1.contains("*")) {
												sp1 = Integer
														.toString(currentLC);
											} else if (SymbolTable
													.symbolIsDefined(op1)) {
												String usage = SymbolTable
														.returnUsage(op1);
												if (usage.toUpperCase()
														.contains("EXT")) {
													code1 = "C";
													sp1 = op1;
												} else if (usage.toUpperCase()
														.contains("LABEL")) {
													sp1 = Integer
															.toString(OperandEvaluator
																	.getOperandValue(op1));
												} else {
													code1 = "A";
													sp1 = op1;
												}
											} else if (OperandType
													.isNumber(op1)) {
												code1 = "A";
												sp1 = op1;
											}

											if (op2 != null) {
												if (op2.charAt(0) == '-') {
													sign2 = "-";
													op2 = op2.substring(1);
												} else {
													op2 = op2.substring(1);
												}
												numOfOps++;
												if (SymbolTable
														.symbolIsDefined(op2)) {
													String usage = SymbolTable
															.returnUsage(op2);
													if (usage.toUpperCase()
															.contains("EXT")) {
														code2 = "C";
														sp2 = op2;
													} else if (usage
															.toUpperCase()
															.contains("LABEL")) {
														sp2 = Integer
																.toString(OperandEvaluator
																		.getOperandValue(op2));
													} else {
														code1 = "A";
														sp2 = Integer
																.toString(OperandEvaluator
																		.getOperandValue(op2));
													}
												} else if (OperandType
														.isNumber(op2)) {
													code2 = "A";
													sp2 = op2;
												}
											}
											if (op3 != null) {
												if (op3.charAt(0) == '-') {
													sign3 = "-";
													op3 = op3.substring(1);
												} else {
													op3 = op3.substring(1);
												}
												numOfOps++;
												if (SymbolTable
														.symbolIsDefined(op3)) {
													String usage = SymbolTable
															.returnUsage(op3);
													if (usage.toUpperCase()
															.contains("EXT")) {
														code3 = "C";
														sp3 = op3;
													} else if (usage
															.toUpperCase()
															.contains("LABEL")) {
														sp3 = Integer
																.toString(OperandEvaluator
																		.getOperandValue(op3));
													} else {
														code1 = "A";
														sp3 = Integer
																.toString(OperandEvaluator
																		.getOperandValue(op3));
													}
												} else if (OperandType
														.isNumber(op3)) {
													code3 = "A";
													sp3 = op3;
												}
											}
											if (op4 != null) {
												if (op4.charAt(0) == '-') {
													sign4 = "-";
													op4 = op4.substring(1);
												} else {
													op4 = op4.substring(1);
												}
												numOfOps++;
												sign4 = "+";
												if (SymbolTable
														.symbolIsDefined(op4)) {
													String usage = SymbolTable
															.returnUsage(op4);
													if (usage.toUpperCase()
															.contains("EXT")) {
														code4 = "C";
														sp4 = op4;
													} else if (usage
															.toUpperCase()
															.contains("LABEL")) {
														sp4 = Integer
																.toString(OperandEvaluator
																		.getOperandValue(op4));
													} else {
														code1 = "A";
														sp4 = Integer
																.toString(OperandEvaluator
																		.getOperandValue(op4));
													}
												} else if (OperandType
														.isNumber(op4)) {
													code4 = "A";
													sp4 = op4;
												}

											}
											if (op5 != null) {
												if (op5.charAt(0) == '-') {
													sign5 = "-";
													op5 = op5.substring(1);
												} else {
													op5 = op5.substring(1);
												}
												numOfOps++;
												sign5 = "+";
												if (SymbolTable
														.symbolIsDefined(op5)) {
													String usage = SymbolTable
															.returnUsage(op5);
													if (usage.toUpperCase()
															.contains("EXT")) {
														code5 = "C";
														sp5 = op5;
													} else if (usage
															.toUpperCase()
															.contains("LABEL")) {
														sp5 = Integer
																.toString(OperandEvaluator
																		.getOperandValue(op5));
													} else {
														code1 = "A";
														sp5 = Integer
																.toString(OperandEvaluator
																		.getOperandValue(op5));
													}
												} else if (OperandType
														.isNumber(op5)) {
													code5 = "A";
													sp5 = op5;
												}

											}
											if (numOfOps == 1) {
												ObjectFile.addTextRecord(
														currentLC, macCode,
														code1, sign1, sp1);
											} else if (numOfOps == 2) {
												ObjectFile.addTextRecord(
														currentLC, macCode,
														code1, sign1, sp1,
														code2, sign2, sp2);
											} else if (numOfOps == 3) {
												ObjectFile.addTextRecord(
														currentLC, macCode,
														code1, sign1, sp1,
														code2, sign2, sp2,
														code3, sign3, sp3);
											} else if (numOfOps == 4) {
												ObjectFile.addTextRecord(
														currentLC, macCode,
														code1, sign1, sp1,
														code2, sign2, sp2,
														code3, sign3, sp3,
														code4, sign4, sp4);
											} else if (numOfOps == 5) {
												ObjectFile.addTextRecord(
														currentLC, macCode,
														code1, sign1, sp1,
														code2, sign2, sp2,
														code3, sign3, sp3,
														code4, sign4, sp4,
														code5, sign5, sp5);
											}
										} else {
											if (OperandEvaluator.usedLocal) {
												if (OperandEvaluator.numberOfLocals > 1) {
													macCode = "0";
													while (macCode.length() < 24) {
														macCode = "0" + macCode;
													}
													String operand = AssemblyListing
															.returnFullOperand(lineNumber);
													String[] operandA = ParseLine
															.parseExpressionKeepOperators(operand);

													int numOfOps = 1;
													String op1 = operandA[0];
													String op2 = operandA[1];
													String op3 = operandA[2];
													String op4 = operandA[3];
													String op5 = operandA[4];
													String sign1 = "+";
													String sign2 = "+";
													String sign3 = "+";
													String sign4 = "+";
													String sign5 = "+";
													String code1 = "C";
													String code2 = "C";
													String code3 = "C";
													String code4 = "C";
													String code5 = "C";
													String sp1 = "0";
													String sp2 = "0";
													String sp3 = "0";
													String sp4 = "0";
													String sp5 = "0";

													if (op1.charAt(0) == '-') {
														sign1 = "-";
														op1 = op1.substring(1);
													}

													if (op1.contains("*")) {
														sp1 = Integer
																.toString(currentLC);
													} else if (SymbolTable
															.symbolIsDefined(op1)) {
														String usage = SymbolTable
																.returnUsage(op1);
														if (usage
																.toUpperCase()
																.contains(
																		"LABEL")) {
															code1 = "C";
															sp1 = Integer
																	.toString(OperandEvaluator
																			.getOperandValue(op1));
														} else {
															code1 = "A";
															sp1 = Integer
																	.toString(OperandEvaluator
																			.getOperandValue(op1));
														}
													} else if (OperandType
															.isNumber(op1)) {
														code1 = "A";
														sp1 = op1;
													}
													if (op2 != null) {
														if (op2.charAt(0) == '-') {
															sign2 = "-";;
														} 
														op2 = op2.substring(1);
														
														numOfOps++;
														if (SymbolTable
																.symbolIsDefined(op2)) {
															String usage = SymbolTable
																	.returnUsage(op2);
															if (usage
																	.toUpperCase()
																	.contains(
																			"LABEL")) {
																code2 = "C";
																sp2 = Integer
																		.toString(OperandEvaluator
																				.getOperandValue(op2));
															} else {
																code2 = "A";
																sp2 = Integer
																		.toString(OperandEvaluator
																				.getOperandValue(op2));
															}
														} else if (OperandType
																.isNumber(op2)) {
															code2 = "A";
															sp2 = op2;
														}
													}
													if (op3 != null) {
														if (op3.charAt(0) == '-') {
															sign3 = "-";
														}
														op3 = op3.substring(1);
														numOfOps++;
														if (SymbolTable
																.symbolIsDefined(op3)) {
															String usage = SymbolTable
																	.returnUsage(op3);
															if (usage
																	.toUpperCase()
																	.contains(
																			"LABEL")) {
																code3 = "C";
																sp3 = Integer
																		.toString(OperandEvaluator
																				.getOperandValue(op3));
															} else {
																code3 = "A";
																sp3 = Integer
																		.toString(OperandEvaluator
																				.getOperandValue(op3));
															}
														} else if (OperandType
																.isNumber(op3)) {
															code3 = "A";
															sp3 = op3;
														}
													}
													if (op4 != null) {
														if (op4.charAt(0) == '-') {
															sign4 = "-";
														}
														op4 = op4.substring(1);
														numOfOps++;
														if (SymbolTable
																.symbolIsDefined(op4)) {
															String usage = SymbolTable
																	.returnUsage(op4);
															if (usage
																	.toUpperCase()
																	.contains(
																			"LABEL")) {
																code4 = "C";
																sp4 = Integer
																		.toString(OperandEvaluator
																				.getOperandValue(op4));
															} else {
																code4 = "A";
																sp4 = Integer
																		.toString(OperandEvaluator
																				.getOperandValue(op4));
															}
														} else if (OperandType
																.isNumber(op4)) {
															code4 = "A";
															sp4 = op4;
														}
													}
													if (op5 != null) {
														if (op5.charAt(0) == '-') {
															sign5 = "-";
															op5 = op5
																	.substring(1);
														}
														numOfOps++;
														if (SymbolTable
																.symbolIsDefined(op5)) {
															String usage = SymbolTable
																	.returnUsage(op5);
															if (usage
																	.toUpperCase()
																	.contains(
																			"LABEL")) {
																code5 = "C";
																sp5 = Integer
																		.toString(OperandEvaluator
																				.getOperandValue(op5));
															} else {
																code5 = "A";
																sp5 = Integer
																		.toString(OperandEvaluator
																				.getOperandValue(op5));
															}
														} else if (OperandType
																.isNumber(op5)) {
															code5 = "A";
															sp5 = op5;
														}
													}
													if (numOfOps == 1) {
														ObjectFile
																.addTextRecord(
																		currentLC,
																		macCode,
																		code1,
																		sign1,
																		sp1);
													} else if (numOfOps == 2) {
														ObjectFile
																.addTextRecord(
																		currentLC,
																		macCode,
																		code1,
																		sign1,
																		sp1,
																		code2,
																		sign2,
																		sp2);
													} else if (numOfOps == 3) {
														ObjectFile
																.addTextRecord(
																		currentLC,
																		macCode,
																		code1,
																		sign1,
																		sp1,
																		code2,
																		sign2,
																		sp2,
																		code3,
																		sign3,
																		sp3);
													} else if (numOfOps == 4) {
														ObjectFile
																.addTextRecord(
																		currentLC,
																		macCode,
																		code1,
																		sign1,
																		sp1,
																		code2,
																		sign2,
																		sp2,
																		code3,
																		sign3,
																		sp3,
																		code4,
																		sign4,
																		sp4);
													} else if (numOfOps == 5) {
														ObjectFile
																.addTextRecord(
																		currentLC,
																		macCode,
																		code1,
																		sign1,
																		sp1,
																		code2,
																		sign2,
																		sp2,
																		code3,
																		sign3,
																		sp3,
																		code4,
																		sign4,
																		sp4,
																		code5,
																		sign5,
																		sp5);
													}

												} else {
													String operand = AssemblyListing
															.returnFullOperand(lineNumber);
													String[] parsedOps = ParseLine
															.parseExpressionKeepOperators(operand);
													int numOperands = 0;
													for (String op : parsedOps) {
														if (op != null) {
															numOperands++;
														}
													}
													if (numOperands == 1) {
														String op1 = parsedOps[0];
														String code1 = "A";
														String sign1 = "+";
														if (op1.charAt(0) == '-') {
															op1 = op1
																	.substring(1);
															sign1 = "-";
														}

														if (op1.contains("*")) {
															op1 = Integer
																	.toString(currentLC);
														}

														if (SymbolTable
																.symbolIsDefined(op1)) {
															String usage = SymbolTable
																	.returnUsage(op1);
															op1 = Integer
																	.toString(OperandEvaluator
																			.getOperandValue(op1));
															if (usage
																	.toUpperCase()
																	.contains(
																			"LABEL")) {
																code1 = "R";
															}
														}

														ObjectFile
																.addTextRecord(
																		currentLC,
																		macCode,
																		code1,
																		sign1,
																		op1);
													} else if (numOperands == 2) {
														String op1 = parsedOps[0];
														String op2 = parsedOps[1];
														String code1 = "A";
														String code2 = "A";
														String sign1 = "+";
														String sign2 = "+";
														if (op1.charAt(0) == '-') {
															sign1 = "-";
															op1 = op1
																	.substring(1);
														}

														if (op2.charAt(0) == '-') {
															sign2 = "-";
														}
														op2 = op2.substring(1);

														if (op1.contains("*")) {
															op1 = Integer
																	.toString(currentLC);
														}

														if (SymbolTable
																.symbolIsDefined(op1)) {
															String usage = SymbolTable
																	.returnUsage(op1);
															op1 = Integer
																	.toString(OperandEvaluator
																			.getOperandValue(op1));
															if (usage
																	.toUpperCase()
																	.contains(
																			"LABEL")) {
																code1 = "R";
															}
														}

														if (SymbolTable
																.symbolIsDefined(op2)) {
															String usage = SymbolTable
																	.returnUsage(op2);
															op2 = Integer
																	.toString(OperandEvaluator
																			.getOperandValue(op2));
															if (usage
																	.toUpperCase()
																	.contains(
																			"LABEL")) {
																code2 = "R";
															}
														}

														ObjectFile
																.addTextRecord(
																		currentLC,
																		macCode,
																		code1,
																		sign1,
																		op1,
																		code2,
																		sign2,
																		op2);
													} else if (numOperands == 3) {
														String op1 = parsedOps[0];
														String op2 = parsedOps[1];
														String op3 = parsedOps[2];
														String code1 = "A";
														String code2 = "A";
														String code3 = "A";
														String sign1 = "+";
														String sign2 = "+";
														String sign3 = "+";
														if (op1.charAt(0) == '-') {
															op1 = op1
																	.substring(1);
															sign1 = "-";
														}
														if (op2.charAt(0) == '-') {
															sign2 = "-";
														}
														op2 = op2.substring(1);
														if (op3.charAt(0) == '-') {
															sign3 = "-";
														}
														op3 = op3.substring(1);

														if (op1.contains("*")) {
															op1 = Integer
																	.toString(currentLC);
														}

														if (SymbolTable
																.symbolIsDefined(op1)) {
															String usage = SymbolTable
																	.returnUsage(op1);
															op1 = Integer
																	.toString(OperandEvaluator
																			.getOperandValue(op1));
															if (usage
																	.toUpperCase()
																	.contains(
																			"LABEL")) {
																code1 = "R";
															}
														}

														if (SymbolTable
																.symbolIsDefined(op2)) {
															String usage = SymbolTable
																	.returnUsage(op2);
															op2 = Integer
																	.toString(OperandEvaluator
																			.getOperandValue(op2));
															if (usage
																	.toUpperCase()
																	.contains(
																			"LABEL")) {
																code2 = "R";
															}
														}
														if (SymbolTable
																.symbolIsDefined(op3)) {
															String usage = SymbolTable
																	.returnUsage(op3);
															op3 = Integer
																	.toString(OperandEvaluator
																			.getOperandValue(op3));
															if (usage
																	.toUpperCase()
																	.contains(
																			"LABEL")) {
																code3 = "R";
															}
														}
														ObjectFile
																.addTextRecord(
																		currentLC,
																		macCode,
																		code1,
																		sign1,
																		op1,
																		code2,
																		sign2,
																		op2,
																		code3,
																		sign3,
																		op3);
													}
												}
											}
										}
									}
								} else {
									String operand = AssemblyListing
											.returnFullOperand(lineNumber);
									String sign = "+";
									String code = "A";
									if (operand.charAt(0) == '-') {
										sign = "-";
										operand = operand.substring(1);
									}
									if (SymbolTable.symbolIsDefined(operand)) {
										String usage = SymbolTable
												.returnUsage(operand);
										operand = Integer
												.toString(OperandEvaluator
														.getOperandValue(operand));
										if (usage.toUpperCase().contains(
												"LABEL")) {
											code = "R";
										}
									}
									ObjectFile.addTextRecord(currentLC,
											macCode, code, sign, operand);
								}
							}
						} else if (currentInst.toUpperCase().contains(
								"SKIP-MEM")) {
							processLineAsNOP();
						} else if (currentInst.toUpperCase().contains("NOP")) {
							processLineAsNOP();
						} else if (currentInst.toUpperCase().contains("COMP")) {
							String originalSourceCode = AssemblyListing
									.returnSourceCodeLine(lineNumber);
							String BRbit = AssemblyListing
									.returnBRBit(lineNumber);
							String Bugbit = AssemblyListing
									.returnDebugBit(lineNumber);
							String fullOperand = AssemblyListing
									.returnFullOperand(lineNumber);
							String[] operands = ParseLine
									.parseExpressionKeepOperators(fullOperand);

							// remove equals from the end of the store location
							String storeLocation = operands[0].substring(0,
									operands[0].length() - 1);

							Main.appendDebugText("COMP STORE LOCATION: "
									+ storeLocation);

							// remove the store location from the operand array
							operands = OperandEvaluator.removeArrayItem(0,
									operands);

							// evaluate what's to the right of the equals and
							// make it a word num
							String wordNumValue = Integer
									.toBinaryString(OperandEvaluator
											.evalutateExpression(operands));
							Main.appendDebugText("EVALUATION OF COMP = "
									+ Integer.parseInt(wordNumValue, 2));

							// add leading zeros if less than 24 bits
							while (wordNumValue.length() < 24) {
								wordNumValue = "0" + wordNumValue;
							}

							Main.appendDebugText("The " + wordNumValue.length()
									+ "-bit representation is " + wordNumValue);

							// replace the COMP with a word-num of what it
							// evaluates to
							AssemblyListing.editRelocationCode(lineNumber, "C");
							AssemblyListing.addObjectCode(lineNumber,
									wordNumValue);
							ObjectFile.addTextRecord(currentLC, wordNumValue,
									"A", "+", Integer.toString(Integer
											.parseInt(wordNumValue, 2)));

							// insert the LD-AC *-1 line as the next line
							AssemblyListing.newLine(lineNumber + 1,
									originalSourceCode + " --> LD-AC *-1");
							AssemblyListing.addBinaryOperation(lineNumber + 1,
									"000000");
							AssemblyListing.addOperation(lineNumber + 1,
									"LD-AC");
							AssemblyListing.addFullOperand(lineNumber + 1,
									"*-1");
							AssemblyListing.addLocationCounter(lineNumber + 1,
									currentLC + 1);
							AssemblyListing
									.turnOnRelativeAddressing(lineNumber + 1);

							if (BRbit.contains("1")) {
								AssemblyListing.turnOnBR(lineNumber + 1);
							}

							if (Bugbit.contains("1")) {
								AssemblyListing.turnOnDebug(lineNumber + 1);
							}

							AssemblyListing.finishLine(lineNumber + 1);

							// insert the ST-AC line as the line after the LD-AC
							AssemblyListing.newLine(lineNumber + 2,
									originalSourceCode + " --> ST-AC "
											+ storeLocation);
							AssemblyListing.addBinaryOperation(lineNumber + 2,
									"000001");
							AssemblyListing.addOperation(lineNumber + 2,
									"ST-AC");
							AssemblyListing.addFullOperand(lineNumber + 2,
									storeLocation);
							AssemblyListing.addLocationCounter(lineNumber + 2,
									currentLC + 2);
							AssemblyListing
									.turnOnRelativeAddressing(lineNumber + 2);

							if (BRbit.contains("1")) {
								AssemblyListing.turnOnBR(lineNumber + 2);
							}

							if (Bugbit.contains("1")) {
								AssemblyListing.turnOnDebug(lineNumber + 2);
							}

							AssemblyListing.finishLine(lineNumber + 2);
							totalCodeLength = AssemblyListing.size();
						}
					}
				}
			}
			lineNumber++;
		}

	}

	private static void processLineAsNOP() {
		String addrFlags = AssemblyListing.returnAddressFlags(lineNumber);
		String IRbit = "0";
		String ARbit = "0";
		String BRbit = AssemblyListing.returnBRBit(lineNumber);
		String Bugbit = AssemblyListing.returnDebugBit(lineNumber);

		String macCode = "011100" + IRbit + ARbit + BRbit + Bugbit + addrFlags;

		// add zeros for address field
		while (macCode.length() < 24) {
			macCode = macCode + "0";
		}
		AssemblyListing.addObjectCode(lineNumber, macCode);
		ObjectFile.addTextRecord(currentLC, macCode, "A", "+", "0");
	}

	/**
	 * Module Name: symbolTable
	 * 
	 * Description: returns the final sorted symbol table
	 * 
	 * Calling Sequence: SymbolTable = passTwo.symbolTable();
	 * 
	 * Input Parameters: none
	 * 
	 * Output Parameters: (SymbolTable) this is the final symbol table after
	 * pass two has been completed
	 * 
	 * Error Conditions Tested:
	 * 
	 * Error Messages Generated:
	 * 
	 * Original Author:
	 * 
	 * Procedure Creation Date:
	 * 
	 * Modification Log: Who/When/Why
	 * 
	 * Coding Standards Met: "Signed Code Leader(Jaron)"
	 * 
	 * Testing Standards Met: "Signed Test Leader(Jamie)"
	 */
	public SymbolTable symbolTable() {
		return PassTwo.symbolTable;

	}

	/**
	 * Module Name: objectFile
	 * 
	 * Description: returns the final object file from pass two
	 * 
	 * Calling Sequence: ObjectFile = passTwo.objectFile();
	 * 
	 * Input Parameters: none
	 * 
	 * Output Parameters: (ObjectFile) this is the final object file from pass
	 * two
	 * 
	 * Error Conditions Tested:
	 * 
	 * Error Messages Generated:
	 * 
	 * Original Author:
	 * 
	 * Procedure Creation Date:
	 * 
	 * Modification Log: Who/When/Why
	 * 
	 * Coding Standards Met: "Signed Code Leader(Jaron)"
	 * 
	 * Testing Standards Met: "Signed Test Leader(Jamie)"
	 */
	public ObjectFile objectFile() {
		return PassTwo.objectFile;

	}

	/**
	 * Module Name: assemblyListing
	 * 
	 * Description: returns the final assembly listing from pass two
	 * 
	 * Calling Sequence: AssemblyListing = passTwo.assemblyListing();
	 * 
	 * Input Parameters: none
	 * 
	 * Output Parameters: (AssemblyListing) this is the final assembly listing
	 * from pass two
	 * 
	 * Error Conditions Tested:
	 * 
	 * Error Messages Generated:
	 * 
	 * Original Author:
	 * 
	 * Procedure Creation Date:
	 * 
	 * Modification Log: Who/When/Why
	 * 
	 * Coding Standards Met: "Signed Code Leader(Jaron)"
	 * 
	 * Testing Standards Met: "Signed Test Leader(Jamie)"
	 */
	public AssemblyListing assemblyListing() {
		return PassTwo.assemblyListing;

	}
}
